home *** CD-ROM | disk | FTP | other *** search
/ SGI ONC3 NFS v3 / SGI ONC3 NFS v3.iso / dist / dist6.5 / nfs.idb / usr / include / cachefs / cachefs_fs.h.z / cachefs_fs.h
C/C++ Source or Header  |  1998-05-06  |  52KB  |  1,509 lines

  1. /*
  2.  * Copyright (c) 1992, Sun Microsystems, Inc.
  3.  * All rights reserved.
  4.  */
  5.  
  6. #ifndef _SYS_FS_CACHEFS_FS_H
  7. #define    _SYS_FS_CACHEFS_FS_H
  8.  
  9. /* #pragma ident    "@(#)cachefs_fs.h    1.62    94/01/05 SMI" */
  10.  
  11. #include <sys/vfs.h>
  12. #include <sys/types.h>
  13. #include <sys/sema.h>
  14. #include <sys/cred.h>
  15. #include <sys/sysmacros.h>
  16. #include <sys/buf.h>
  17. #include <sys/capability.h>
  18. #include <string.h>
  19. #include <sys/dirent.h>
  20. #if _KERNEL
  21. #include <sys/atomic_ops.h>
  22. #include <sys/kmem.h>
  23. #include <sys/immu.h>
  24. #include <sys/pda.h>
  25. #include <sys/systm.h>
  26. #include <sys/vnode.h>
  27. #endif /* _KERNEL */
  28.  
  29. #ifdef __cplusplus
  30. extern "C" {
  31. #endif
  32.  
  33. #define CFS_DEF_DIR            "/cache"
  34. #define CFS_DEF_ACREGMIN    3
  35. #define CFS_DEF_ACREGMAX    60
  36. #define CFS_DEF_ACDIRMIN    30
  37. #define CFS_DEF_ACDIRMAX    60
  38.  
  39. /*
  40.  * CacheFS block size definitions
  41.  */
  42. #define FRONT_BSIZE(CP)        (C_TO_FSCACHE(CP)->fs_cache->c_bsize)
  43. #define BACK_BSIZE(CP)        (C_TO_FSCACHE(CP)->fs_bsize)
  44. #define CFS_BMAPSIZE(CP)    (C_TO_FSCACHE(CP)->fs_bmapsize)
  45. #define CFS_BOFFSET(CP)        (C_TO_FSCACHE(CP)->fs_bmapsize - 1)
  46. #define CFS_BMASK(CP)        (~CFS_BOFFSET(CP))
  47. #define CFS_SAME_BLOCK(CP, OFF1, OFF2)    \
  48.     (((OFF1) & CFS_BMASK(CP)) == ((OFF2) & CFS_BMASK(CP)))
  49.  
  50. #define MAXCFSREADAHEAD    10
  51. #define NCFSREADMAPS    MAXCFSREADAHEAD + 1
  52. #define NCFSWRITEMAPS    1
  53. extern int cachefs_readahead;
  54. extern int front_dio;
  55.  
  56. #if defined(ROUNDUP)
  57. #undef ROUNDUP
  58. #endif /* ROUNDUP */
  59.  
  60. /*
  61.  * round a up to the nearest b, where a and b area arbitrary integers
  62.  */
  63. #define ROUNDUP(a, b)    ((((a) + (b) - 1) / (b)) * (b))
  64.  
  65. /*
  66.  * flags for cachefs_flushvp()
  67.  */
  68. #define CFS_INVAL        0x1
  69. #define CFS_FREE        0x2
  70. #define CFS_TRUNC        0x4
  71.  
  72. #define GCWAIT_TIME        60
  73.  
  74. #define CACHEFS_LOGMODE        0600
  75. #define CACHEFS_FILEMODE    0600
  76. #define CACHEFS_DIRMODE        0700
  77.  
  78. /*
  79.  * type definition for longlong
  80.  */
  81. typedef __uint64_t longlong_t;
  82.  
  83. /*
  84.  * alias kcred to sys_cred
  85.  */
  86. #define kcred    sys_cred
  87.  
  88. #ifdef DEBUG
  89.  
  90. #define _CNODE_TRACE        /* enable cnode tracing */
  91.  
  92. #define CFS_TRACEBUFLEN  16
  93.  
  94. struct trace_record {
  95.     int        tr_id;            /* trace record ID */
  96.     void    *tr_addr;        /* calling function */
  97.     int        tr_line;        /* source line number */
  98.     long    tr_val[3];        /* arguments */
  99. };
  100.  
  101. typedef struct trace_record tracerec_t;
  102.  
  103. struct cfstrace {
  104.     int         ct_index;
  105.     int         ct_wrap;
  106.     tracerec_t  ct_buffer[CFS_TRACEBUFLEN];
  107.     lock_t        ct_lock;
  108. };
  109.  
  110. typedef struct cfstrace cfstrace_t;
  111. #endif /* DEBUG */
  112.  
  113. /* Some default values */
  114. #define    DEF_POP_SIZE        0x10000        /* 64K */
  115. #define    CFSVERSION            3
  116. #define    CACHELABEL_NAME        ".cfs_label"
  117. #define    BACKMNT_NAME        ".cfs_mnt_points"
  118. #define    CACHEFS_ROOTNAME    "root"
  119.  
  120. /*
  121.  * cachefs_sys commands
  122.  */
  123. #define CACHEFSSYS_REPLACEMENT        1    /* replacement daemon */
  124. #define CACHEFSSYS_CHECKFID            2    /* check a FID to see if it is valid */
  125. #define CACHEFSSYS_RECONNECT        3    /* reconnection daemon */
  126. #define CACHEFSSYS_MOUNT            4    /* disconnected mount completion */
  127.  
  128. /*
  129.  * all the stuff needed to manage a queue of requests to be processed
  130.  * by async threads.
  131.  */
  132. struct cachefs_workq {
  133.     struct cachefs_req    *wq_head;        /* head of work q */
  134.     struct cachefs_req    *wq_tail;        /* tail of work q */
  135.     int                    wq_length;        /* # of requests on q */
  136.     int                    wq_thread_count;    /* total # of threads */
  137.     int                    wq_thread_busy;        /* # of busy threads */
  138.     int                    wq_max_len;        /* longest queue */
  139.     u_int                wq_halt_request:1;    /* halt requested */
  140.     u_int                wq_keepone:1;        /* keep one thread */
  141.     sv_t                wq_req_sv;        /* wait on work to do */
  142.     sv_t                wq_halt_sv;        /* wait/signal halt */
  143.     lock_t                wq_queue_lock;        /* protect queue */
  144. };
  145.  
  146. typedef struct cachefscache cachefscache_t;
  147.  
  148. #define    CNODE_BUCKET_SIZE    1597
  149. #define FSID_MAP_SLOTS        31
  150.  
  151. struct fsidmap {
  152.     dev_t            fsid_back;    /* back FS attributed fsid */
  153.     dev_t            fsid_cachefs; /* cachefs-unique fsid */
  154.     struct fsidmap  *fsid_next; /* other mappings */
  155. };
  156.  
  157. /*
  158.  * CacheFS minor device number allocation bitmap.
  159.  */
  160. #define MINORMAPSIZE    (256/NBBY)
  161.  
  162. struct minormap {
  163.     u_char    vec[MINORMAPSIZE];
  164. };
  165.  
  166. /*
  167.  * fscache structure contains per-filesystem information, both filesystem
  168.  * cache directory information and mount-specific information.
  169.  */
  170. struct fscache {
  171.     char                 *fs_cacheid;    /* File system ID */
  172.     int                     fs_flags;
  173.     struct cachefscache    *fs_cache;    /* back ptr to cache struct */
  174.     u_int                 fs_options;    /* mount options */
  175.     bhv_desc_t            fs_bhv;    /* vfs cachefs behavior */
  176.     struct vfs            *fs_backvfsp;    /* back vfsp */
  177.     struct vfs            *fs_frontvfsp;    /* front vfsp */
  178.     struct vnode        *fs_rootvp;    /* root vnode ptr */
  179.     struct cnode        *fs_root;    /* root cnode ptr */
  180.     int                     fs_vnoderef;    /* activate vnode ref count */
  181.     struct vnode        *fs_cacheidvp;    /* front FS cacheid dir vnode */
  182.     struct cachefsops    *fs_cfsops;    /* cfsops vector pointer */
  183.     u_int                 fs_acregmin;    /* same as nfs values */
  184.     u_int                 fs_acregmax;
  185.     u_int                 fs_acdirmin;
  186.     u_int                 fs_acdirmax;
  187.     struct fscache        *fs_next;    /* ptr to next fscache */
  188.     struct cnode        *fs_cnode[CNODE_BUCKET_SIZE]; /* hash buckets */
  189.     struct cnode        *fs_cnode_by_fid[CNODE_BUCKET_SIZE];
  190.     struct cnode        *fs_reclaim;    /* list of cnodes to be freed */
  191.     u_int                fs_hashvers;    /* hash version */
  192.     off_t                fs_bsize;    /* back FS block size */
  193.     off_t                fs_bmapsize;    /* FS block size for bmap */
  194.     u_int                fs_sync_running;    /* sync is running or not */
  195.     struct fsidmap        *fs_fsidmap[FSID_MAP_SLOTS];
  196.     mutex_t                fs_fsidmaplock;    /* protects fsid map */
  197.     lock_t                fs_fslock;
  198.     /* protect contents - everyting xcept the cnode hash */
  199.     mutex_t                fs_cnodelock;    /* protects creation of cnodes */
  200.     sv_t                fs_sync_wait;    /* wait point for umount sync */
  201.     sv_t                fs_reconnect;    /* wait for reconnection */
  202. };
  203. typedef struct fscache fscache_t;
  204.  
  205. /* valid fscache flags */
  206. #define    CFS_FS_MOUNTED        1    /* fscache is mounted */
  207. #define    CFS_FS_READ            2    /* fscache can be read */
  208. #define    CFS_FS_WRITE        4    /* fscache can be written */
  209.  
  210. #define FSC_TO_BACKVFS(FSCP)    (FSCP)->fs_backvfsp
  211. #define FSC_TO_FRONTVFS(FSCP)    (FSCP)->fs_frontvfsp
  212. #define FSC_TO_VFS(FSCP)    bhvtovfs((&(FSCP)->fs_bhv))
  213.  
  214. #define    CFSOP_INIT_COBJECT(FSCP, CP, VAP, CR)    \
  215.     (*(FSCP)->fs_cfsops->co_init_cobject)(FSCP, CP, VAP, CR)
  216. #define    CFSOP_CHECK_COBJECT(FSCP, CP, VAP, CR, LM)    \
  217.     (*(FSCP)->fs_cfsops->co_check_cobject)(FSCP, CP, VAP, CR, LM)
  218. #define    CFSOP_MODIFY_COBJECT(FSCP, CP, CR)    \
  219.     (*(FSCP)->fs_cfsops->co_modify_cobject)(FSCP, CP, CR)
  220. #define    CFSOP_INVALIDATE_COBJECT(FSCP, CP, CR)    \
  221.     (*(FSCP)->fs_cfsops->co_invalidate_cobject)(FSCP, CP, CR)
  222. #define    CFSOP_EXPIRE_COBJECT(FSCP, CP, CR)    \
  223.     (*(FSCP)->fs_cfsops->co_expire_cobject)(FSCP, CP, CR)
  224.  
  225. #define    C_ISFS_WRITE_AROUND(FSCP) ((FSCP)->fs_options & CFS_WRITE_AROUND)
  226. #define    C_ISFS_STRICT(FSCP) \
  227.     (((FSCP)->fs_options & CFS_WRITE_AROUND) && \
  228.     (((FSCP)->fs_options & CFS_NOCONST_MODE) == 0))
  229. #define    C_ISFS_SINGLE(FSCP) ((FSCP)->fs_options & CFS_DUAL_WRITE)
  230. #define    C_ISFS_NOCONST(FSCP) ((FSCP)->fs_options & CFS_NOCONST_MODE)
  231. #define C_ISFS_DISCONNECT(FSCP)    ((FSCP)->fs_options & CFS_DISCONNECT)
  232. #define C_ISFS_NONBLOCK(FSCP)    ((FSCP)->fs_options & CFS_NONBLOCK)
  233. #define C_ISFS_PRIVATE(FSCP)    ((FSCP)->fs_options & CFS_PRIVATE)
  234.  
  235. /*
  236.  * Front FS vnode operation macros.
  237.  */
  238. #define FRONT_VOP_GETATTR(cp, attrp, flag, credp) \
  239.     cachefs_frontop_getattr(cp, attrp, flag, credp)
  240. #define FRONT_VOP_SETATTR(cp, attrp, flags, credp) \
  241.     cachefs_frontop_setattr(cp, attrp, flags, credp)
  242. #define FRONT_VOP_FSYNC(cp, syncflag, credp, start, stop) \
  243.     cachefs_frontop_fsync(cp, syncflag, credp, start, stop)
  244. #define FRONT_VOP_LOOKUP(dcp, nm, vpp, pnp, flags, rdir, credp) \
  245.     cachefs_frontop_lookup(dcp, nm, vpp, pnp, flags, rdir, credp)
  246. #define FRONT_VOP_LINK(tdcp, cp, tnm, credp) \
  247.     cachefs_frontop_link(tdcp, cp, tnm, credp)
  248. #define FRONT_VOP_LOOKUP(dcp, nm, vpp, pnp, flags, rdir, credp) \
  249.     cachefs_frontop_lookup(dcp, nm, vpp, pnp, flags, rdir, credp)
  250. #define FRONT_VOP_RENAME(odcp, onm, ndcp, nnm, pnp, credp) \
  251.     cachefs_frontop_rename(odcp, onm, ndcp, nnm, pnp, credp)
  252. #define FRONT_VOP_REMOVE(dcp, nm, credp) cachefs_frontop_remove(dcp, nm, credp)
  253. #define FRONT_VOP_FID(cp, fidpp) cachefs_frontop_fid(cp, fidpp)
  254. #define FRONT_VOP_FID2(cp, fidp) cachefs_frontop_fid2(cp, fidp)
  255.  
  256. /*
  257.  * Back FS vnode operation macros.
  258.  */
  259. enum backop_mode {BACKOP_BLOCK, BACKOP_NONBLOCK};
  260.  
  261. #define BACK_VOP_GETATTR(cp, attrp, flag, credp, mode, errorp) \
  262.     cachefs_backop_getattr(cp, attrp, flag, credp, mode, errorp)
  263. #define BACK_VOP_READDIR(cp, uiop, credp, eofp, mode, errorp) \
  264.     cachefs_backop_readdir(cp, uiop, credp, eofp, mode, errorp)
  265. #define BACK_VOP_SETATTR(cp, attrp, flags, credp, mode, errorp) \
  266.     cachefs_backop_setattr(cp, attrp, flags, credp, mode, errorp)
  267. #define BACK_VOP_ACCESS(cp, mode, credp, opmode, errorp) \
  268.     cachefs_backop_access(cp, mode, credp, opmode, errorp)
  269. #define BACK_VOP_READLINK(cp, uiop, credp, mode, errorp) \
  270.     cachefs_backop_readlink(cp, uiop, credp, mode, errorp)
  271. #define BACK_VOP_CREATE(dcp, nm, vap, excl, mode, devvpp, credp, opmode, errorp)\
  272.     cachefs_backop_create(dcp, nm, vap, excl, mode, devvpp, credp, opmode, \
  273.         errorp)
  274. #define BACK_VOP_REMOVE(dcp, nm, credp, mode, errorp) \
  275.     cachefs_backop_remove(dcp, nm, credp, mode, errorp)
  276. #define BACK_VOP_LINK(tdcp, cp, tnm, credp, mode, errorp) \
  277.     cachefs_backop_link(tdcp, cp, tnm, credp, mode, errorp)
  278. #define BACK_VOP_RENAME(odcp, onm, ndcp, nnm, pnp, credp, mode, errorp) \
  279.     cachefs_backop_rename(odcp, onm, ndcp, nnm, pnp, credp, mode, errorp)
  280. #define BACK_VOP_MKDIR(dcp, nm, va, vpp, credp, mode, errorp) \
  281.     cachefs_backop_mkdir(dcp, nm, va, vpp, credp, mode, errorp)
  282. #define BACK_VOP_RMDIR( dcp, nm, cdir, credp, mode, errorp) \
  283.     cachefs_backop_rmdir(dcp, nm, cdir, credp, mode, errorp)
  284. #define BACK_VOP_SYMLINK(dcp, lnm, tva, tnm, credp, mode, errorp) \
  285.     cachefs_backop_symlink(dcp, lnm, tva, tnm, credp, mode, errorp)
  286. #define BACK_VOP_FRLOCK(cp, cmd, bfp, flag, offset, credp, mode, vrwlock, errorp) \
  287.     cachefs_backop_frlock(cp, cmd, bfp, flag, offset, credp, mode, vrwlock, errorp)
  288. #define BACK_VOP_FCNTL(cp, cmd, arg, flags, offset, cr, rvp, mode, errorp) \
  289.     cachefs_backop_fcntl(cp, cmd, arg, flags, offset, cr, rvp, mode, errorp)
  290. #define BACK_VOP_VNODE_CHANGE(cp, cmd, val, mode) \
  291.     cachefs_backop_vnode_change(cp, cmd, val, mode)
  292.  
  293. #define BACK_VOP_ATTR_GET(cp, name, value, valuelenp, flags, credp, mode, errorp) \
  294.     cachefs_backop_attr_get(cp, name, value, valuelenp, flags, credp, mode, errorp)
  295. #define BACK_VOP_ATTR_SET(cp, name, value, valuelen, flags, credp, mode, errorp) \
  296.     cachefs_backop_attr_set(cp, name, value, valuelen, flags, credp, mode, errorp)
  297. #define BACK_VOP_ATTR_REMOVE(cp, name, flags, credp, mode, errorp) \
  298.     cachefs_backop_attr_remove(cp, name, flags, credp, mode, errorp)
  299. #define BACK_VOP_ATTR_LIST(cp, buffer, bufsize, flags, cursor, credp, mode, errorp) \
  300.     cachefs_backop_attr_list(cp, buffer, bufsize, flags, cursor, credp, mode, errorp)
  301.  
  302. /*
  303.  * back FS vfs operations
  304.  */
  305. #define BACK_VFS_STATVFS(fscp, sbp, opmode, errorp) \
  306.     cachefs_backop_statvfs(fscp, sbp, opmode, errorp)
  307.  
  308. #define NET_VOP_FID(vp, fidpp, opmode, error, status) { \
  309.     int retry = 0; \
  310.     do { \
  311.         CACHEFS_STATS->cs_backvnops++; \
  312.         VOP_FID(vp, fidpp, error); \
  313.         switch (error) { \
  314.             case 0: \
  315.                 status = BACKOP_SUCCESS; \
  316.                 retry = 0; \
  317.                 break; \
  318.             case ETIMEDOUT: \
  319.             case ENETDOWN: \
  320.             case ENETUNREACH: \
  321.             case ECONNREFUSED: \
  322.             case ENOBUFS: \
  323.             case ECONNABORTED: \
  324.             case ENETRESET: \
  325.             case ECONNRESET: \
  326.             case ENONET: \
  327.             case ESHUTDOWN: \
  328.             case EHOSTDOWN: \
  329.             case EHOSTUNREACH: \
  330.                 if (opmode == BACKOP_BLOCK) { \
  331.                     retry = 1; \
  332.                 } else { \
  333.                     retry = 0; \
  334.                 } \
  335.                 status = BACKOP_NETERR; \
  336.                 CACHEFS_STATS->cs_neterror++; \
  337.                 CFS_DEBUG(CFSDEBUG_NETERR, \
  338.                     printf("NET_VOP_GETATTR(%s, line %d): network error %d %s %s\n", \
  339.                         __FILE__, __LINE__, error, \
  340.                         (opmode == BACKOP_BLOCK) ? "BACKOP_BLOCK" : \
  341.                         "BACKOP_NONBLOCK", retry ? "retry" : "")); \
  342.                 break; \
  343.             case ESTALE: \
  344.             default: \
  345.                 status = BACKOP_FAILURE; \
  346.                 retry = 0; \
  347.         } \
  348.     } while (retry); \
  349. }
  350.  
  351. #define NET_VOP_GETATTR_NOSTAT(vp, attrp, flag, credp, opmode, error) { \
  352.     int retry = 0; \
  353.     do { \
  354.         CACHEFS_STATS->cs_backvnops++; \
  355.         CACHEFS_STATS->cs_backops.cb_get++; \
  356.         VOP_GETATTR(vp, attrp, flag, credp, error); \
  357.         switch (error) { \
  358.             case 0: \
  359.                 retry = 0; \
  360.                 break; \
  361.             case ETIMEDOUT: \
  362.             case ENETDOWN: \
  363.             case ENETUNREACH: \
  364.             case ECONNREFUSED: \
  365.             case ENOBUFS: \
  366.             case ECONNABORTED: \
  367.             case ENETRESET: \
  368.             case ECONNRESET: \
  369.             case ENONET: \
  370.             case ESHUTDOWN: \
  371.             case EHOSTDOWN: \
  372.             case EHOSTUNREACH: \
  373.                 if (opmode == BACKOP_BLOCK) { \
  374.                     retry = 1; \
  375.                 } else { \
  376.                     retry = 0; \
  377.                 } \
  378.                 CACHEFS_STATS->cs_neterror++; \
  379.                 CFS_DEBUG(CFSDEBUG_NETERR, \
  380.                     printf("NET_VOP_GETATTR(%s, line %d): network error %d %s %s\n", \
  381.                         __FILE__, __LINE__, error, \
  382.                         (opmode == BACKOP_BLOCK) ? "BACKOP_BLOCK" : \
  383.                         "BACKOP_NONBLOCK", retry ? "retry" : "")); \
  384.                 break; \
  385.             case ESTALE: \
  386.             default: \
  387.                 retry = 0; \
  388.         } \
  389.     } while (retry); \
  390. }
  391.  
  392. #define NET_VOP_GETATTR(vp, attrp, flag, credp, opmode, error, status) { \
  393.     int retry = 0; \
  394.     do { \
  395.         CACHEFS_STATS->cs_backvnops++; \
  396.         CACHEFS_STATS->cs_backops.cb_get++; \
  397.         VOP_GETATTR(vp, attrp, flag, credp, error); \
  398.         switch (error) { \
  399.             case 0: \
  400.                 status = BACKOP_SUCCESS; \
  401.                 retry = 0; \
  402.                 break; \
  403.             case ETIMEDOUT: \
  404.             case ENETDOWN: \
  405.             case ENETUNREACH: \
  406.             case ECONNREFUSED: \
  407.             case ENOBUFS: \
  408.             case ECONNABORTED: \
  409.             case ENETRESET: \
  410.             case ECONNRESET: \
  411.             case ENONET: \
  412.             case ESHUTDOWN: \
  413.             case EHOSTDOWN: \
  414.             case EHOSTUNREACH: \
  415.                 if (opmode == BACKOP_BLOCK) { \
  416.                     retry = 1; \
  417.                 } else { \
  418.                     retry = 0; \
  419.                 } \
  420.                 status = BACKOP_NETERR; \
  421.                 CACHEFS_STATS->cs_neterror++; \
  422.                 CFS_DEBUG(CFSDEBUG_NETERR, \
  423.                     printf("NET_VOP_GETATTR(%s, line %d): network error %d %s %s\n", \
  424.                         __FILE__, __LINE__, error, \
  425.                         (opmode == BACKOP_BLOCK) ? "BACKOP_BLOCK" : \
  426.                         "BACKOP_NONBLOCK", retry ? "retry" : "")); \
  427.                 break; \
  428.             case ESTALE: \
  429.             default: \
  430.                 status = BACKOP_FAILURE; \
  431.                 retry = 0; \
  432.         } \
  433.     } while (retry); \
  434. }
  435.  
  436. #define NET_VFS_STATVFS(vfsp, sbp, vp, opmode, error, status) { \
  437.     int retry = 0; \
  438.     do { \
  439.         CACHEFS_STATS->cs_backvfsops++; \
  440.         VFS_STATVFS(vfsp, sbp, vp, error); \
  441.         switch (error) { \
  442.             case 0: \
  443.                 status = BACKOP_SUCCESS; \
  444.                 retry = 0; \
  445.                 break; \
  446.             case ETIMEDOUT: \
  447.             case ENETDOWN: \
  448.             case ENETUNREACH: \
  449.             case ECONNREFUSED: \
  450.             case ENOBUFS: \
  451.             case ECONNABORTED: \
  452.             case ENETRESET: \
  453.             case ECONNRESET: \
  454.             case ENONET: \
  455.             case ESHUTDOWN: \
  456.             case EHOSTDOWN: \
  457.             case EHOSTUNREACH: \
  458.                 if (opmode == BACKOP_BLOCK) { \
  459.                     retry = 1; \
  460.                 } else { \
  461.                     retry = 0; \
  462.                 } \
  463.                 status = BACKOP_NETERR; \
  464.                 CACHEFS_STATS->cs_neterror++; \
  465.                 CFS_DEBUG(CFSDEBUG_NETERR, \
  466.                     printf("NET_VFS_STATVFS(%s, line %d): network error %d %s %s\n", \
  467.                         __FILE__, __LINE__, error, \
  468.                         (opmode == BACKOP_BLOCK) ? \
  469.                         "BACKOP_BLOCK" : "BACKOP_NONBLOCK", \
  470.                         retry ? "retry" : "")); \
  471.                 break; \
  472.             case ESTALE: \
  473.             default: \
  474.                 status = BACKOP_FAILURE; \
  475.                 retry = 0; \
  476.         } \
  477.     } while (retry); \
  478. }
  479.  
  480. /*
  481.  * One cache_label structure per cache. Contains mainly user defined or
  482.  * default values for cache resource management. Contents is static.
  483.  */
  484. struct cache_label {
  485.     u_int    cl_cfsversion:16;/* cfs version number */
  486.     u_int    cl_cfslongsize:8;/* size of type long for which cache was created */
  487.     u_int    cl_cfsmetasize:8;/* size of metadata structure in file headers */
  488.     int        cl_minio;        /* minimum direct I/O transfer size */
  489.     int        cl_align;        /* direct I/O alignment */
  490.     int        cl_maxblks;    /* max blocks to be used by cache */
  491.     int        cl_blkhiwat;    /* high water-mark for block usage */
  492.     int        cl_blklowat;    /* low water-mark for block usage */
  493.     int        cl_maxfiles;    /* max front files/dirs to be used by cache */
  494.     int        cl_filehiwat;    /* high water-mark for inode usage */
  495.     int        cl_filelowat;    /* low water-mark for indoe usage */
  496. };
  497.  
  498. /*
  499.  * struct cache contains cache-wide information, and provides access
  500.  * to lower level info. There is one cache structure per cache.
  501.  */
  502. struct cachefscache {
  503.     struct cachefscache    *c_next;    /* list of caches */
  504.     u_int            c_flags;    /* misc flags */
  505.     char                *c_name;
  506.     struct cache_label    c_label;    /* cache resource info */
  507.     struct vnode        *c_labelvp;    /* label file vp */
  508.     struct vnode        *c_dirvp;    /* cache directory vp */
  509.     int                    c_syncs;    /* number of syncs in progress */
  510.     int                    c_refcnt;    /* active fs ref count */
  511.     struct fscache        *c_fslist;    /* fscache list head */
  512.     struct cachefs_workq    c_workq;    /* async work */
  513.     lock_t            c_contentslock; /* protect cache struct */
  514.     mutex_t            c_fslistlock;    /* protect fscache list */
  515.     off_t            c_bsize;    /* block size to use for front file system */
  516.     off_t            c_bmapsize;    /* block size to use for bmap */
  517.     sv_t            c_replacement_sv;
  518.     sv_t            c_repwait_sv;
  519. #if defined(DEBUG) && defined(_CACHE_TRACE)
  520.     cfstrace_t        c_trace;    /* cachefscache trace records */
  521. #endif /* DEBUG && _CACHE_TRACE */
  522. };
  523.  
  524. /*
  525.  * Various cache structure flags.
  526.  */
  527. #define CACHE_GCDAEMON_HALT        0x01    /* replacement daemon should exit */
  528. #define CACHE_GCDAEMON_ACTIVE    0x02    /* replacement daemon is active */
  529. #define CACHE_GARBAGE_COLLECT    0x04    /* replacement is needed */
  530. #define CACHE_GCDAEMON_WAITING    0x08    /* replacement daemon is waiting */
  531.  
  532. /*
  533.  * Values for the cachefs options flag.
  534.  */
  535. /*
  536.  * Mount options
  537.  */
  538. #define    CFS_WRITE_AROUND    0x001    /* write-around */
  539. #define    CFS_DUAL_WRITE        0x002    /* write to cache and back file */
  540. #define    CFS_NOCONST_MODE    0x008    /* no-op consistency mode */
  541. #define    CFS_ACCESS_BACKFS    0x010    /* pass VOP_ACCESS to backfs */
  542. #define    CFS_PURGE            0x020    /* force purge of cache */
  543. #define CFS_DISCONNECT        0x040    /* disconnected operation */
  544. #define CFS_NONBLOCK        0x080    /* non-blocking for all back FS ops */
  545. #define CFS_ADD_BACK        0x100    /* add back FS */
  546. #define CFS_PRIVATE            0x200    /* do file and record locking locally */
  547. #define CFS_NO_BACKFS        0x400    /* no back file system mounted */
  548.  
  549. /*
  550.  * cachefs mount structure and related data
  551.  */
  552. struct cachefs_mountargs {
  553.     u_int            cfs_options;    /* consistency modes, etc. */
  554.     char            *cfs_cacheid;    /* CFS fscdir name */
  555.     char            *cfs_cachedir;    /* path for this cache dir */
  556.     char            *cfs_backfs;    /* back filesystem dir */
  557.     u_int            cfs_acregmin;    /* same as nfs values */
  558.     u_int            cfs_acregmax;
  559.     u_int            cfs_acdirmin;
  560.     u_int            cfs_acdirmax;
  561. };
  562.  
  563. #ifdef _KERNEL
  564. /*
  565.  * IRIX 5 mount args
  566.  */
  567. struct irix5_cachefs_mountargs {
  568.     u_int            cfs_options;    /* consistency modes, etc. */
  569.     app32_ptr_t        cfs_cacheid;    /* CFS fscdir name */
  570.     app32_ptr_t        cfs_cachedir;    /* path for this cache dir */
  571.     app32_ptr_t        cfs_backfs;        /* back filesystem dir */
  572.     u_int            cfs_acregmin;    /* same as nfs values */
  573.     u_int            cfs_acregmax;
  574.     u_int            cfs_acdirmin;
  575.     u_int            cfs_acdirmax;
  576. };
  577. #endif /* _KERNEL */
  578.  
  579. /*
  580.  * replaceent arguments, etc.
  581.  */
  582.  
  583. /*
  584.  * replacement list entries
  585.  */
  586. struct cachefs_replace {
  587.     char    *rep_cacheid;            /* cache ID for purged file */
  588.     char    *rep_path;                /* path name of front file */
  589. };
  590. typedef struct cachefs_replace cachefsrep_t;
  591.  
  592. struct cachefsrepl_arg {
  593.     char            *ra_cachedir;
  594.     int                ra_ents;
  595.     cachefsrep_t    *ra_list;
  596.     int                ra_timeout;
  597. };
  598. typedef struct cachefsrepl_arg replarg_t;
  599.  
  600. #ifdef _KERNEL
  601. struct irix5_cachefs_replace {
  602.     app32_ptr_t    rep_cacheid;            /* cache ID for purged file */
  603.     app32_ptr_t    rep_path;                /* path name of front file */
  604. };
  605. typedef struct irix5_cachefs_replace irix5_cachefsrep_t;
  606.  
  607. struct irix5_cachefsrepl_arg {
  608.     app32_ptr_t        ra_cachedir;
  609.     int                ra_ents;
  610.     app32_ptr_t        ra_list;
  611.     int                ra_timeout;
  612. };
  613. typedef struct irix5_cachefsrepl_arg irix5_replarg_t;
  614. #endif /* _KERNEL */
  615.  
  616. /*
  617.  * checkfid args, etc.
  618.  */
  619. struct checkfidarg {
  620.     dev_t        cf_fsid;            /* the dev num of the mounted file system */
  621.     fid_t        cf_fid;                /* the file ID to be checked */
  622. };
  623. typedef struct checkfidarg checkfidarg_t;
  624.  
  625. #if _KERNEL
  626. enum lockmode { READLOCKED, WRITELOCKED, UNLOCKED, NOLOCK };
  627. typedef enum lockmode lockmode_t;
  628.  
  629. /*
  630.  * struct cachefsops - consistency modules.
  631.  */
  632. struct cachefsops {
  633.     int        (* co_init_cobject)(struct fscache *, struct cnode *, vattr_t *,
  634.                 cred_t *);
  635.     int        (* co_check_cobject)(struct fscache *, struct cnode *, vattr_t *,
  636.                 cred_t *, lockmode_t);
  637.     void    (* co_modify_cobject)(struct fscache *, struct cnode *, cred_t *);
  638.     void    (* co_invalidate_cobject)(struct fscache *, struct cnode *,
  639.                 cred_t *);
  640.     void    (* co_expire_cobject)(struct fscache *, struct cnode *, cred_t *);
  641. };
  642. #endif /* _KERNEL */
  643.  
  644. /*
  645.  * Stuff for the file header.
  646.  */
  647.  
  648. #define FILEHEADER_SIZE    BBSIZE
  649.  
  650. /*
  651.  * Cache consistency mechanism token size.  This size is expressed in
  652.  * long units.  It is expressed this way for alignment purposes.
  653.  */
  654. #define MAXTOKENSIZE    4
  655.  
  656. typedef long        ctoken_t[MAXTOKENSIZE];
  657.  
  658. /*
  659.  * File block allocation map entry.
  660.  * File allocation accounting is done in the number of units specified in
  661.  * the metadata.  This value is derived from what the front FS said was its
  662.  * preferred I/O size.  Specifically, it is the preferred I/O size divided
  663.  * by BBSIZE (i.e., the number of basic blocks per preferred I/O size).
  664.  */
  665. struct allocation_map {
  666.     off_t        am_start_off;    /* starting offset of contiguous bytes */
  667.     off_t        am_size;        /* number of contiguous bytes */
  668. };
  669. typedef struct allocation_map allocmap_t;
  670.  
  671. /*
  672.  * Cachefs file attributes.
  673.  */
  674. struct cattr {
  675. #if _KERNEL
  676.     vtype_t        ca_type;    /* vnode type (for create) */
  677. #else
  678.     int        ca_type;
  679. #endif
  680.     __uint64_t    ca_mode;    /* file access mode */
  681.     __uint64_t    ca_uid;        /* owner user id */
  682.     __uint64_t    ca_gid;        /* owner group id */
  683.     __uint64_t    ca_fsid;    /* file system id */
  684.     __uint64_t    ca_nodeid;    /* node id */
  685.     __uint64_t    ca_nlink;    /* number of references to file */
  686.     __uint64_t    ca_size;    /* file size in bytes */
  687.     timespec_t    ca_atime;    /* time of last access */
  688.     timespec_t    ca_mtime;    /* time of last modification */
  689.     timespec_t    ca_ctime;    /* time file ``created'' */
  690.     __uint64_t    ca_rdev;    /* device the file represents */
  691.     __uint64_t    ca_nblocks;    /* # of blocks allocated */
  692.     __uint64_t    ca_vcode;    /* version code */
  693. };
  694. typedef struct cattr cattr_t;
  695.  
  696. #define VATTR_TO_CATTR(VP, VA, CA, FL)    { \
  697.     (CA)->ca_type = (VA)->va_type; \
  698.     (CA)->ca_mode = (__uint64_t)(VA)->va_mode; \
  699.     (CA)->ca_uid = (__uint64_t)(VA)->va_uid; \
  700.     (CA)->ca_gid = (__uint64_t)(VA)->va_gid; \
  701.     (CA)->ca_fsid = (__uint64_t)(VA)->va_fsid; \
  702.     (CA)->ca_nodeid = (__uint64_t)(VA)->va_nodeid; \
  703.     (CA)->ca_nlink = (__uint64_t)(VA)->va_nlink; \
  704.     (CA)->ca_atime = (VA)->va_atime; \
  705.     (CA)->ca_mtime = (VA)->va_mtime; \
  706.     (CA)->ca_ctime = (VA)->va_ctime; \
  707.     (CA)->ca_rdev = (__uint64_t)(VA)->va_rdev; \
  708.     (CA)->ca_nblocks = (__uint64_t)(VA)->va_nblocks; \
  709.     (CA)->ca_vcode = (__uint64_t)(VA)->va_vcode; \
  710.     if ((FL) & AT_SIZE) (CA)->ca_size = (__uint64_t)(VA)->va_size; \
  711.         if (MANDLOCK(VP, (CA)->ca_mode) != ((VP)->v_flag & VENF_LOCKING)) \
  712.                 VOP_VNODE_CHANGE(VP, VCHANGE_FLAGS_ENF_LOCKING, \
  713.                                  MANDLOCK(VP, (CA)->ca_mode)); \
  714. }
  715.  
  716. #define CATTR_TO_VATTR(CA, VA)    { \
  717.     bzero(VA, sizeof(vattr_t)); \
  718.     (VA)->va_type = (CA)->ca_type; \
  719.     (VA)->va_mode = (mode_t)(CA)->ca_mode; \
  720.     (VA)->va_uid = (uid_t)(CA)->ca_uid; \
  721.     (VA)->va_gid = (gid_t)(CA)->ca_gid; \
  722.     (VA)->va_fsid = (dev_t)(CA)->ca_fsid; \
  723.     (VA)->va_nodeid = (ino_t)(CA)->ca_nodeid; \
  724.     (VA)->va_nlink = (nlink_t)(CA)->ca_nlink; \
  725.     (VA)->va_size = (off_t)(CA)->ca_size; \
  726.     (VA)->va_atime = (CA)->ca_atime; \
  727.     (VA)->va_mtime = (CA)->ca_mtime; \
  728.     (VA)->va_ctime = (CA)->ca_ctime; \
  729.     (VA)->va_rdev = (dev_t)(CA)->ca_rdev; \
  730.     (VA)->va_nblocks = (blkcnt_t)(CA)->ca_nblocks; \
  731.     (VA)->va_vcode = (u_long)(CA)->ca_vcode; \
  732. }
  733.  
  734. /*
  735.  * File state and attributes.
  736.  * This structure has been constructed so that the first four fields may
  737.  * be accessed by user programs regardless of what size long those programs
  738.  * use.  The size of this initial segment is 44 bytes.
  739.  */
  740. struct cachefs_metadata {
  741.     u_int        md_checksum;        /* file header checksum */
  742.     u_short        md_state;            /* file state (see flags below) */
  743.     u_short        md_allocents;        /* number of valid allocation map entries */
  744.     fid_t        md_backfid;            /* back file ID */
  745.     ctoken_t    md_token;            /* cache consistency token */
  746.     cattr_t        md_attributes;        /* file attributes from the back FS */
  747. };
  748. typedef struct cachefs_metadata cachefsmeta_t;
  749.  
  750. /*
  751.  * File state flags.
  752.  */
  753. #define MD_POPULATED        0x0001    /* the file has been populated */
  754. #define MD_MDVALID            0x0002    /* the file metadata contents are valid */
  755. #define MD_NOALLOCMAP        0x0004    /* file/symlink data is in allocation map */
  756. #define MD_KEEP                0x0010    /* do not discard the metadata */
  757. #define MD_INIT                0x0020    /* initial metadata */
  758. #define MD_NOTRUNC            0x0040    /* filenames are not truncated */
  759.  
  760. #define VALID_MD_STATE(state)    (((state) & ~(MD_POPULATED | MD_MDVALID | MD_NOALLOCMAP | MD_KEEP | MD_INIT | MD_NOTRUNC)) == 0)
  761.  
  762. /*
  763.  * The allocation map size is dependent upon the size of cachefsmeta_t.
  764.  * The entire file header must fit into FILEHEADER_SIZE bytes.  There is
  765.  * also the constraint that the allocation map must be 8-byte aligned.
  766.  */
  767. #define OFFSET_MASK        (sizeof(off_t) - 1)
  768. #define ALLOCMAP_SIZE    \
  769.     ((FILEHEADER_SIZE - ((sizeof(cachefsmeta_t) + OFFSET_MASK) & ~OFFSET_MASK)) / sizeof(allocmap_t))
  770.  
  771. struct file_header {
  772.     cachefsmeta_t    fh_metadata;
  773.     allocmap_t        fh_allocmap[ALLOCMAP_SIZE];
  774. };
  775. typedef struct file_header fileheader_t;
  776.  
  777. /*
  778.  * the file header occupies a block of minimum size defined by the minimum
  779.  * direct I/O transfer size
  780.  * file data starts after the file header
  781.  */
  782. #define FILEHEADER_BLOCK_SIZE(cachep)    FILEHEADER_SIZE
  783. #define DATA_START(cachep)                FILEHEADER_BLOCK_SIZE(cachep)
  784. #define DIO_ALIGNMENT(cachep)            ((cachep)->c_label.cl_align)
  785.  
  786. /*
  787.  * cnode structure, one per file. Cnode hash bucket kept in fscache
  788.  * structure below.
  789.  */
  790.  
  791. #if _KERNEL
  792. /*
  793.  * LOCKS:    rwlock        Read / Write serialization
  794.  *        statelock    Protects other fields
  795.  */
  796. struct cnode {
  797.     int                    c_flags;
  798.     vtype_t                c_type;
  799.     int                    c_refcnt;
  800.     struct cnode        *c_hash;    /* hash list pointer */
  801.     struct cnode        *c_hash_by_fid;    /* hash list pointer */
  802.     struct cnode        *c_dcp;        /* parent directory cnode */
  803.     struct vnode        *c_frontvp;    /* front vnode pointer */
  804.     struct vnode        *c_frontdirvp;    /* front dir vnode pointer */
  805.     struct vnode        *c_backvp;    /* back vnode pointer */
  806.     struct vnode        *c_vnode;    /* vnode itself */
  807.     bhv_desc_t            c_bhv_desc;    /* CacheFS behavior */
  808.     fid_t                c_frontfid;    /* front file ID */
  809.     fid_t                c_frontdirfid;    /* front directory ID */
  810.     fid_t                *c_backfid;        /* back file ID/hash key */
  811.     fileheader_t        *c_fileheader;    /* file header data */
  812.     cattr_t                *c_attr;    /* cached attributes */
  813.     off_t                c_size;        /* client view of the size */
  814.     ctoken_t            *c_token;        /* consistency token */
  815.     int                    c_error;
  816.     off_t                c_written;    /* pending write byte count */
  817.     int                    c_nio;        /* Number of io's pending */
  818.     u_int                c_ioflags;
  819.     cred_t                *c_cred;
  820.     fscache_t            *c_fscache;    /* pointer to fscache structure for cnode */
  821.     sv_t                c_iosv;        /* IO sync var. */
  822.     krwlock_t            c_rwlock;    /* serialize lock */
  823.     lock_t                c_statelock;    /* statelock */
  824.     lock_t                c_iolock;
  825.     sv_t                c_popwait_sv;
  826.     sv_t                c_valloc_wait;
  827. #ifdef DEBUG
  828. #ifdef _CNODE_TRACE
  829.     cfstrace_t            c_trace;        /* cnode tracing */
  830. #endif
  831.     u_int                c_inhash;        /* in or out of hash indicator */
  832.     u_int                c_infidhash;    /* in or out of fid hash indicator */
  833. #endif /* DEBUG */
  834. };
  835.  
  836. typedef struct cnode cnode_t;
  837.  
  838. /*
  839.  * Conversion macros
  840.  */
  841. #define    BHVTOC(BDP)        ((struct cnode *)BHV_PDATA(BDP))
  842. #define    CTOBHV(CP)        (&((CP)->c_bhv_desc))
  843. #define    CTOV(CP)        ((vnode_t *)((void *)(((CP)->c_vnode))))
  844. #define    BHVTOFSCACHE(VFSP)    ((struct fscache *)BHV_PDATA(bdp))
  845. #define    C_TO_FSCACHE(CP)    ((CP)->c_fscache)
  846. #define C_DIRTY(CP)        (VN_DIRTY(CTOV(CP)) || ((CP)->c_written != 0))
  847.  
  848. #define CN_HOLD(CP)        atomicAddInt(&(CP)->c_refcnt, 1);
  849. #define CN_RELE(CP)        atomicAddInt(&(CP)->c_refcnt, -1);
  850.  
  851. #define VALID_CACHEFS_VNODE(vp)    \
  852.     (((vp)->v_type != VNON) && ((vp)->v_op == &cachefs_vnodeops) && (vp)->v_vfsp && (vp)->v_data && ((void *)VTOC(vp)->c_fscache == (vp)->v_vfsp->vfs_data))
  853.  
  854. /*
  855.  * Various flags stored in the flags field of the cnode structure.
  856.  */
  857. #define    CN_NOCACHE                0x0001    /* the object is not being cached */
  858. #define    CN_DESTROY                0x0002    /* destroy cnode when inactive */
  859. #define    CN_ROOT                    0x0004    /* root of the file system */
  860. #define    CN_INVAL                0x0008    /* object invalidation in progress */
  861. #define    CN_MODIFIED                0x0010    /* Object has been written to */
  862. #define CN_UPDATED                0x0020    /* metadata has been updated */
  863. #define CN_POPULATION_PENDING    0x0040    /* population in progress */
  864. #define CN_SYNC                    0x0080    /* cnode is being synced */
  865. #define CN_UPDATE_PENDING        0x0100    /* metadata update in progress */
  866. #define CN_NEEDINVAL            0x0200    /* need to do object invalidation */
  867. #define CN_REPLACE                0x0400    /* front file removed by replacement */
  868. #define CN_WRITTEN                0x0800    /* file written to since last sync */
  869. #define CN_FRLOCK                0x1000    /* file and record locking performed */
  870. #define CN_RECLAIM                0x2000    /* cnode is being reclaimed */
  871. #define CN_VALLOC                0x4000    /* vnode allocation in progress */
  872.  
  873. #define C_CACHING(CP)    (!((CP)->c_flags & CN_NOCACHE) && \
  874.     (CP)->c_frontfid.fid_len)
  875.  
  876. /*
  877.  * io flags (in c_ioflag)
  878.  */
  879. #define    CIO_ASYNCWRITE    0x1        /* async write pending: off==0, len==0 */
  880. #define    CIO_ASYNCREAD    0x2        /* async read pending: off==0, len==0 */
  881.  
  882. #define    CHASH(FILENO) \
  883.     ((int)(((((FILENO) >> 22) & 0x7ff) ^ (((FILENO) >> 11) & 0x7ff) ^ \
  884.         ((FILENO) & 0x7ff)) % (CNODE_BUCKET_SIZE)))
  885.  
  886. #define FID_MATCH(fp1, fp2) \
  887.     (((fp1)->fid_len == (fp2)->fid_len) && \
  888.     (bcmp((caddr_t)(fp1)->fid_data, (caddr_t)(fp2)->fid_data, \
  889.         (fp1)->fid_len) == 0))
  890.  
  891. extern int cachefs_max_threads;
  892.  
  893. #define    CFS_ASYNC_TIMEOUT    60
  894.  
  895. enum cachefs_cmd {
  896.     CFS_POPULATE_DIR,
  897.     CFS_POPULATE_FILE,
  898.     CFS_CACHE_SYNC,
  899.     CFS_ASYNCWRITE,
  900.     CFS_ASYNCREAD,
  901.     CFS_NOOP
  902. };
  903.  
  904. struct cachefs_fs_sync_req {
  905.     struct cachefscache *cf_cachep;
  906. };
  907.  
  908. struct cachefs_popfile_req {
  909.     cnode_t *cpf_cp;
  910. };
  911.  
  912. struct cachefs_popdir_req {
  913.     cnode_t *cpd_cp;
  914. };
  915.  
  916. struct cachefs_io_req {
  917.     cnode_t *cp_cp;
  918.     struct buf    *cp_buf;
  919.     int cp_flags;
  920. };
  921.  
  922. struct cachefs_req {
  923.     struct cachefs_req    *cfs_next;
  924.     enum cachefs_cmd    cfs_cmd;    /* Command to execute */
  925.     cred_t *cfs_cr;
  926.     union {
  927.         struct cachefs_fs_sync_req cu_fs_sync;
  928.         struct cachefs_io_req cu_io;
  929.         struct cachefs_popfile_req cu_popfile;
  930.         struct cachefs_popdir_req cu_popdir;
  931.     } cfs_req_u;
  932. };
  933.  
  934. enum backop_stat {BACKOP_SUCCESS, BACKOP_NETERR, BACKOP_FAILURE};
  935. #endif /* _KERNEL */
  936.  
  937. /*
  938.  * statistics
  939.  */
  940. struct cachefs_stats {
  941.     u_int    cs_inval;            /* invalidations */
  942.     u_int    cs_nocache;            /* nocache */
  943.     u_int    cs_reclaims;        /* reclaims */
  944.     u_int    cs_dnlchit;            /* dnlc lookup hit */
  945.     u_int    cs_shorthit;        /* lookup shortcut hits */
  946.     u_int    cs_shortmiss;        /* lookup shortcut miss */
  947.     u_int    cs_lookuphit;        /* cache lookup hits */
  948.     u_int    cs_lookupstale;        /* stale lookup hits */
  949.     u_int    cs_lookupmiss;        /* cache lookup miss */
  950.     u_int    cs_nocachelookup;    /* nocache lookups */
  951.     u_int    cs_lookups;            /* total number of lookups */
  952.     u_int    cs_readhit;            /* data read hit */
  953.     u_int    cs_readmiss;        /* data read miss */
  954.     u_int    cs_reads;            /* total reads at strategy level */
  955.     u_int    cs_nocachereads;    /* nocache reads */
  956.     u_int    cs_readerrors;        /* read errors */
  957.     u_int    cs_writes;            /* total writes at strategy level */
  958.     u_int    cs_nocachewrites;    /* nocache writes */
  959.     u_int    cs_writeerrors;        /* write errors */
  960.     u_int    cs_readdirhit;        /* readdir hits */
  961.     u_int    cs_readdirmiss;        /* readdir miss */
  962.     u_int    cs_readdirs;        /* total readdirs */
  963.     u_int    cs_vnops;            /* vnode operations */
  964.     u_int    cs_vfsops;            /* vfs operations */
  965.     u_int    cs_objinits;        /* object initializations */
  966.     u_int    cs_objmods;            /* object modification */
  967.     u_int    cs_objinvals;        /* object invalidations */
  968.     u_int    cs_objexpires;        /* explicit object expirations */
  969.     u_int    cs_objchecks;        /* object checks */
  970.     u_int    cs_backchecks;        /* object checks to back FS */
  971.     u_int    cs_newcnodes;        /* count of cnode creations */
  972.     u_int    cs_makecnode;        /* count of calls to makecachefsnode */
  973.     u_int    cs_nocnode;            /* count of ENOENT returns for shortcut */
  974.     u_int    cs_cnodehit;        /* cnodes found by makecachefsnode */
  975.     u_int    cs_cnoderestart;    /* count for number of search restarts */
  976.     u_int    cs_cnodelookagain;    /* count for number of second searches */
  977.     u_int    cs_cnodetoss;        /* cnodes tossed due to duplication */
  978.     u_int    cs_neterror;        /* count of network errors */
  979.     u_int    cs_fronterror;        /* front file errors */
  980.     u_int    cs_shortrdlnk;        /* fast readlink from metadata */
  981.     u_int    cs_longrdlnk;        /* long readlink */
  982.     u_int    cs_backvnops;        /* back FS vnode op calls */
  983.     u_int    cs_backvfsops;        /* back FS vnode op calls */
  984.     u_int    cs_getbackvp;        /* get back vnode requests */
  985.     u_int    cs_asyncreqs;        /* async operation reuests */
  986.     u_int    cs_replacements;    /* replacement requests */
  987.     struct {                    /* bad file headers */
  988.         u_int    cbh_checksum;    /* bad checksum */
  989.         u_int    cbh_readerr;    /* read error */
  990.         u_int    cbh_data;        /* invalid header data */
  991.         u_int    cbh_short;        /* short file header */
  992.     }        cs_badheader;
  993.     struct {                    /* cnode race collision statistics */
  994.         u_int    cr_reclaim;        /* collisions with reclaim */
  995.         u_int    cr_destroy;        /* collisions with destruction */
  996.     }        cs_race;
  997.     struct {                    /* back vnode operations */
  998.         u_int    cb_look;        /* lookup */
  999.         u_int    cb_fsy;            /* fsync */
  1000.         u_int    cb_rdl;            /* readlink */
  1001.         u_int    cb_acc;            /* access */
  1002.         u_int    cb_get;            /* getattr */
  1003.         u_int    cb_set;            /* setattr */
  1004.         u_int    cb_clo;            /* close */
  1005.         u_int    cb_opn;            /* open */
  1006.         u_int    cb_rdd;            /* readdir */
  1007.         u_int    cb_cre;            /* create */
  1008.         u_int    cb_rem;            /* remove */
  1009.         u_int    cb_lnk;            /* link */
  1010.         u_int    cb_ren;            /* rename */
  1011.         u_int    cb_mkd;            /* mkdir */
  1012.         u_int    cb_rmd;            /* rmdir */
  1013.         u_int    cb_sym;            /* symlink */
  1014.         u_int    cb_frl;            /* frlock */
  1015.         u_int    cb_rdv;            /* read */
  1016.         u_int    cb_wrv;            /* write */
  1017.     }        cs_backops;
  1018.     struct {                    /* fileheader cache operations */
  1019.         u_int    cf_hits;        /* file header cache hits */
  1020.         u_int    cf_misses;        /* file header cache misses */
  1021.         u_int    cf_reads;        /* file header reads */
  1022.         u_int    cf_writes;        /* file header writes */
  1023.         u_int    cf_cacheenters;    /* new entries to the cache */
  1024.         u_int    cf_cacheremoves;/* removals of entries from the cache */
  1025.         u_int    cf_lruenters;    /* new entries lru */
  1026.         u_int    cf_lruremoves;    /* removals of entries from the lru */
  1027.         u_int    cf_purges;        /* purges */
  1028.         u_int    cf_releases;    /* releases */
  1029.     } cs_fileheaders;
  1030. };
  1031.  
  1032. /*
  1033.  * file header cache entry structure
  1034.  */
  1035. struct filheader_cache_entry {
  1036.     fileheader_t                    *fce_header;    /* file header  */
  1037.     struct filheader_cache_entry    *fce_next;        /* next cache entry  */
  1038.     struct filheader_cache_entry    *fce_prev;        /* prev cache entry */
  1039.     struct filheader_cache_entry    *fce_lrunext;    /* next LRU entry */
  1040.     struct filheader_cache_entry    *fce_lruprev;    /* prev LRU entry */
  1041.     fid_t                            *fce_fid;        /* front file ID */
  1042.     sv_t                            fce_wait;        /* sync point */
  1043.     u_int                            fce_ref;        /* reference count */
  1044.     u_int                            fce_flags;        /* entry state flags */
  1045.     u_int                            fce_slot;        /* cache slot */
  1046. #ifdef DEBUG
  1047.     void                            *fce_caller;    /* caller address */
  1048. #endif /* DEBUG */
  1049. };
  1050.  
  1051. /*
  1052.  * cache entry flags
  1053.  */
  1054. #define ENTRY_NEW            0x01
  1055. #define ENTRY_DESTROY        0x02
  1056. #define ENTRY_VALID            0x04
  1057. #define ENTRY_LRU            0x08
  1058. #define ENTRY_CACHED        0x10
  1059.  
  1060. #if _KERNEL
  1061. #define CACHEFS_STATS    ((struct cachefs_stats *)private.cfsstat)
  1062.  
  1063. extern int cachefsfstyp;
  1064.  
  1065. #define UIO_SETUP(uiop, iovp, base, len, offset, seg, mode, ulim) { \
  1066.     (iovp)->iov_base = base; \
  1067.     (iovp)->iov_len = len; \
  1068.     (uiop)->uio_iov = iovp; \
  1069.     (uiop)->uio_iovcnt = 1; \
  1070.     (uiop)->uio_offset = offset; \
  1071.     (uiop)->uio_segflg = seg; \
  1072.     (uiop)->uio_resid = len; \
  1073.     (uiop)->uio_limit = ulim; \
  1074.     (uiop)->uio_pmp = NULL; \
  1075.     (uiop)->uio_pio = 0; \
  1076.     (uiop)->uio_readiolog = 0; \
  1077.     (uiop)->uio_writeiolog = 0; \
  1078.     (uiop)->uio_pbuf = 0; \
  1079.     (uiop)->uio_sigpipe = 0; \
  1080.     (uiop)->uio_fmode = mode; \
  1081. }
  1082.  
  1083. #define READ_VP(vp, uiop, ioflag, cr, fl, error) { \
  1084.     VOP_RWLOCK(vp, VRWLOCK_READ); \
  1085.     VOP_READ(vp, uiop, ioflag | IO_ISLOCKED, cr, fl, error); \
  1086.     VOP_RWUNLOCK(vp, VRWLOCK_READ); \
  1087. }
  1088.  
  1089. #define WRITE_VP(vp, uiop, ioflag, cr, fl, error) { \
  1090.     VOP_RWLOCK(vp, \
  1091.         (ioflag & IO_DIRECT) ? VRWLOCK_WRITE_DIRECT : VRWLOCK_WRITE); \
  1092.     VOP_WRITE(vp, uiop, ioflag | IO_ISLOCKED, cr, fl, error); \
  1093.     VOP_RWUNLOCK(vp, \
  1094.         (ioflag & IO_DIRECT) ? VRWLOCK_WRITE_DIRECT : VRWLOCK_WRITE); \
  1095. }
  1096.  
  1097. #define FRONT_READ_VP(cp, uiop, ioflag, cr) \
  1098.     cachefs_frontop_readvp(cp, uiop, ioflag, cr)
  1099.  
  1100. #define FRONT_WRITE_VP(cp, uiop, ioflag, cr) \
  1101.     cachefs_frontop_writevp(cp, uiop, ioflag, cr)
  1102.  
  1103. #define BACK_READ_VP(cp, uiop, ioflag, cr, mode, errorp) \
  1104.     cachefs_backop_readvp(cp, uiop, ioflag, cr, mode, errorp)
  1105.  
  1106. #define BACK_WRITE_VP(cp, uiop, ioflag, cr, mode, errorp) \
  1107.     cachefs_backop_writevp(cp, uiop, ioflag, cr, mode, errorp)
  1108. #endif /* _KERNEL */
  1109.  
  1110. /*
  1111.  * cachefs function prototypes
  1112.  */
  1113. #if defined(_KERNEL) && defined(__STDC__)
  1114.  
  1115. /* cachefs_cnode.c */
  1116. void cachefs_remfidhash(struct cnode *cp);
  1117. void cachefs_remhash(struct cnode *);
  1118. cnode_t *cfind_by_fid(struct fid *, struct fscache *);
  1119. cnode_t *cfind(fid_t *, struct fscache *);
  1120. int cachefs_lookup_cnode( cnode_t *, char *, cnode_t **, cred_t * );
  1121. int cachefs_get_cnode_files( cnode_t *, vnode_t *, vnode_t *, vnode_t * );
  1122. int makecachefsnode( cnode_t *, fid_t *, struct fscache *, fileheader_t *,
  1123.     vnode_t *, vnode_t *, vnode_t *, vattr_t *, cred_t *, int,
  1124.     struct cnode ** );
  1125. void cachefs_cnode_free( struct cnode * );
  1126. int valid_file_header(fileheader_t *fhp, fid_t *backfid);
  1127. int valid_allocmap( cnode_t *cp );
  1128. #ifdef DEBUG
  1129. void validate_fileheader(cnode_t *cp, char *file, int line);
  1130. #endif
  1131.  
  1132. /* cachefs_fscache.c */
  1133. void fscache_destroy(fscache_t *);
  1134. fscache_t *fscache_create(cachefscache_t *, char *, struct cachefs_mountargs *,
  1135.     vnode_t *, vfs_t *);
  1136. void fscache_hold(fscache_t *);
  1137. void fscache_rele(fscache_t *);
  1138. void fscache_sync(struct fscache *, int);
  1139. void fscache_free_cnodes(struct fscache *);
  1140. fscache_t *fscache_list_find(cachefscache_t *, char *);
  1141. void fscache_list_add(cachefscache_t *, fscache_t *);
  1142. void fscache_list_remove(cachefscache_t *, fscache_t *);
  1143. int cachefs_shake(int);
  1144.  
  1145. /* cachefs_subr.c */
  1146. int activate_cache(cachefscache_t *);
  1147. void deactivate_cache(cachefscache_t *);
  1148. int cachefs_cache_create(char **, cachefscache_t **, vnode_t *);
  1149. void cachefs_cache_destroy(cachefscache_t *cachep);
  1150. void cachefs_cache_sync(struct cachefscache *cachep);
  1151. void cachefs_do_req(struct cachefs_req *);
  1152. int cachefs_cnode_cnt(int);
  1153. int cachefs_nocache(cnode_t *);
  1154. int cachefs_inval_object(cnode_t *, lockmode_t);
  1155. int cachefs_async_halt(struct cachefs_workq *);
  1156. int cachefs_check_allocmap(cnode_t *, off_t, off_t);
  1157. int cachefs_update_allocmap(cnode_t *, off_t, off_t);
  1158. u_long cachefs_gettime_cached_object(struct fscache *, vtype_t, u_long);
  1159. cachefscache_t *cachefscache_list_find(char *);
  1160. int cachefs_populate_dir(cnode_t *cp, cred_t *cr);
  1161. int cachefsio_write(struct cnode *cp, struct buf *bp, cred_t *cr);
  1162. int cachefsio_read(struct cnode *cp, struct buf *bp, cred_t *cr);
  1163. void cachefs_workq_init(struct cachefs_workq *);
  1164. void cachefs_workq_destroy(struct cachefs_workq *);
  1165. int cachefs_addqueue(struct cachefs_req *, struct cachefs_workq *);
  1166. void cachefs_inactivate(struct cnode *);
  1167. int cachefs_flushvp(bhv_desc_t *, off_t, size_t, int, uint64_t);
  1168. int cachefs_async_start(cachefscache_t *);
  1169. void cachefs_async_daemon(struct cachefs_workq *);
  1170. void make_ascii_name(fid_t *fidp, char *strp);
  1171. u_int fidhash(struct fid *, u_int);
  1172. #ifdef DEBUG
  1173. int find_fileheader_by_fid(fid_t *, fileheader_t *);
  1174. void idbg_headercache(__psint_t);
  1175. void idbg_checklru(__psint_t);
  1176. #endif /* DEBUG */
  1177. void cachefs_mem_check(void);
  1178. fileheader_t *alloc_fileheader(vnode_t *vp);
  1179. void release_fileheader(fid_t *fidp, fileheader_t *fhp);
  1180. int cachefs_write_file_header(cnode_t *, vnode_t *, fileheader_t *, int, int);
  1181. int cachefs_write_header(cnode_t *cp, int force);
  1182. int cachefs_read_file_header(vnode_t *, fileheader_t **, vtype_t, int, int);
  1183. int cachefs_lookup_frontdir(vnode_t *, fid_t *, vnode_t **);
  1184. int cachefs_create_frontdir(cachefscache_t *, vnode_t *, fid_t *, vnode_t **);
  1185. int cachefs_create_frontfile(cachefscache_t *, vnode_t *, char *, vnode_t **,
  1186.     fid_t *, fileheader_t **, vtype_t);
  1187. int cachefs_remove_frontfile(vnode_t *dvp, char *nm);
  1188. int cachefs_remove_frontdir(fscache_t *fscp, fid_t *backfid, int);
  1189. int cachefs_update_directory(cnode_t *dcp, int flag, cred_t *cr);
  1190. int cachefs_irix5_fmtdirent(void **, struct dirent *, int);
  1191. int await_population(cnode_t *);
  1192. int cachefs_search_dir(cnode_t *dcp, char *nm, lockmode_t lm);
  1193. int cachefs_sys(int, void *, rval_t *);
  1194. #ifdef DEBUG
  1195. int cachefs_name_is_legal(char *);
  1196. int valid_dirents( dirent_t *dep, int dircount );
  1197. #endif
  1198.  
  1199. /* cachefs_resource.c */
  1200. int cachefs_allocblocks(cachefscache_t *, int, cred_t *);
  1201. int cachefs_allocfile(cachefscache_t *);
  1202. void cachefs_replacement_halt(cachefscache_t *);
  1203. int cachefs_replacement(void *, rval_t *);
  1204. int cachefs_reconnect(void *, rval_t *);
  1205. int cachefs_checkfid(void *, rval_t *);
  1206. int cachefs_replace(cachefscache_t *cachep, int wait_for_replace);
  1207.  
  1208. /* cachefs_vnops.c */
  1209. int cachefs_fsync(bhv_desc_t *, int, cred_t *, off_t, off_t);
  1210.  
  1211. /* cachefs_vfsops.c */
  1212. int cachefs_complete_mount(void *, rval_t *);
  1213. dev_t make_cachefs_fsid(fscache_t *, dev_t);
  1214. void release_minor_number(int);
  1215.  
  1216. extern zone_t *Cachefs_fileheader_zone;
  1217. extern zone_t *Cachefs_attr_zone;
  1218. extern zone_t *Cachefs_cnode_zone;
  1219. extern zone_t *Cachefs_fid_zone;
  1220. extern zone_t *Cachefs_path_zone;
  1221. extern zone_t *Cachefs_fhcache_zone;
  1222. extern zone_t *Cachefs_req_zone;
  1223. extern zone_t *Cachefs_fsidmap_zone;
  1224.  
  1225. extern mutex_t cachefs_cachelock;
  1226. extern vattr_t Cachefs_file_attr;
  1227. extern vattr_t Cachefs_dir_attr;
  1228.  
  1229. extern int replacement_timeout;
  1230.  
  1231. /* cachefs_backops.c */
  1232. enum backop_stat cachefs_backop_getattr(cnode_t *, vattr_t *, int, cred_t *,
  1233.     enum backop_mode, int *);
  1234. enum backop_stat cachefs_backop_readdir(cnode_t *, uio_t *, cred_t *, int *,
  1235.     enum backop_mode, int *);
  1236. enum backop_stat cachefs_backop_setattr(cnode_t *, vattr_t *, int, cred_t *,
  1237.     enum backop_mode, int *);
  1238. enum backop_stat cachefs_backop_access(cnode_t *, int, cred_t *,
  1239.     enum backop_mode, int *);
  1240. enum backop_stat cachefs_backop_readlink(cnode_t *, uio_t *, cred_t *,
  1241.     enum backop_mode, int *);
  1242. enum backop_stat cachefs_lookup_back(cnode_t *, char *, struct vnode **,
  1243.     fid_t **, int, struct vnode *, cred_t *, enum backop_mode, int *);
  1244. enum backop_stat cachefs_backop_create(cnode_t *, char *, vattr_t *,
  1245.     int, int, vnode_t **, cred_t *, enum backop_mode, int *);
  1246. enum backop_stat cachefs_backop_remove(cnode_t *, char *, cred_t *,
  1247.     enum backop_mode, int *);
  1248. enum backop_stat cachefs_backop_link(cnode_t *, cnode_t *, char *, cred_t *,
  1249.     enum backop_mode, int *);
  1250. enum backop_stat cachefs_backop_rename(cnode_t *, char *, cnode_t *, char *,
  1251.     struct pathname *, cred_t *, enum backop_mode, int *);
  1252. enum backop_stat cachefs_backop_mkdir(cnode_t *, char *, vattr_t *, vnode_t **,
  1253.     cred_t *, enum backop_mode, int *);
  1254. enum backop_stat cachefs_backop_rmdir(cnode_t *, char *, vnode_t *, cred_t *,
  1255.     enum backop_mode, int *);
  1256. enum backop_stat cachefs_backop_symlink(cnode_t *, char *, vattr_t *, char *,
  1257.     cred_t *, enum backop_mode, int *);
  1258. enum backop_stat cachefs_backop_frlock(cnode_t *, int, struct flock *, int,
  1259.     off_t, cred_t *, enum backop_mode, vrwlock_t, int *);
  1260. enum backop_stat cachefs_backop_readvp(cnode_t *, uio_t *, int, cred_t *,
  1261.     enum backop_mode, int *);
  1262. enum backop_stat cachefs_backop_writevp(cnode_t *, uio_t *, int, cred_t *,
  1263.     enum backop_mode, int *);
  1264. enum backop_stat cachefs_getbackvp(fscache_t *fscp, fid_t *backfid,
  1265.     vnode_t **vpp, enum backop_mode, int *);
  1266. enum backop_stat cachefs_backop_statvfs(fscache_t *, struct statvfs *,
  1267.     enum backop_mode, int *);
  1268. enum backop_stat cachefs_backop_fcntl(cnode_t *cp, int cmd, void *arg,
  1269.     int flags, off_t offset, cred_t *cr, rval_t *rvp, enum backop_mode opmode,
  1270.     int *errorp);
  1271. enum backop_stat cachefs_backop_vnode_change(cnode_t *, vchange_t, __psint_t,
  1272.     enum backop_mode);
  1273. enum backop_stat cachefs_backop_attr_get(cnode_t *, char *, char *, int *,
  1274.                      int, cred_t *, enum backop_mode,
  1275.                      int *);
  1276. enum backop_stat cachefs_backop_attr_set(cnode_t *, char *, char *, int,
  1277.                      int, cred_t *, enum backop_mode,
  1278.                      int *);
  1279. enum backop_stat cachefs_backop_attr_remove(cnode_t *, char *, int, cred_t *,
  1280.                         enum backop_mode, int *);
  1281. struct attrlist_cursor_kern;
  1282. enum backop_stat cachefs_backop_attr_list(cnode_t *, char *, int, int,
  1283.                       struct attrlist_cursor_kern *,
  1284.                       cred_t *, enum backop_mode, int *);
  1285.  
  1286. /* cachefs_frontops.c */
  1287. int cachefs_frontop_getattr(cnode_t *, vattr_t *, int, cred_t *);
  1288. int cachefs_frontop_setattr(cnode_t *, vattr_t *, int, cred_t *);
  1289. int cachefs_frontop_fsync(cnode_t *, int, cred_t *, off_t, off_t);
  1290. int cachefs_frontop_link(cnode_t *, cnode_t *, char *, cred_t *);
  1291. int cachefs_frontop_readvp(cnode_t *, uio_t *, int, cred_t *);
  1292. int cachefs_frontop_writevp(cnode_t *, uio_t *, int, cred_t *);
  1293. int cachefs_frontop_statvfs(fscache_t *, struct statvfs *);
  1294. int cachefs_getfrontdirvp(struct cnode *cp);
  1295. int cachefs_getfrontvp(struct cnode *cp);
  1296. int cachefs_frontop_lookup(cnode_t *, char *, struct vnode **,
  1297.     struct pathname *, int, struct vnode *, cred_t *);
  1298. int cachefs_frontop_remove(cnode_t *, char *, cred_t *);
  1299. int cachefs_frontop_rename(cnode_t *, char *, cnode_t *, char *,
  1300.     struct pathname *, cred_t *);
  1301. int cachefs_frontop_fid(cnode_t *, struct fid **);
  1302. int cachefs_frontop_fid2(cnode_t *, struct fid *);
  1303.  
  1304. #ifdef DEBUG
  1305. struct km_wrap {
  1306.     int kw_size;
  1307.     int kw_req;
  1308.     void *kw_caller;
  1309.     struct km_wrap *kw_other;
  1310.     struct km_wrap *kw_next;
  1311.     struct km_wrap *kw_prev;
  1312. };
  1313.  
  1314. #define WRAPSIZE    ((sizeof(struct km_wrap) + sizeof(void *) - 1) & \
  1315.     ~(sizeof(void *) - 1))
  1316.  
  1317. extern struct km_wrap *Cachefs_memlist;
  1318. extern int cachefs_mem_usage;
  1319. extern int cachefs_zone_usage;
  1320.  
  1321. #define CACHEFS_KMEM_ALLOC(size, flag)    cachefs_kmem_alloc(kmem_alloc, size, \
  1322.     flag)
  1323. #define CACHEFS_KMEM_ZALLOC(size, flag)    cachefs_kmem_alloc(kmem_zalloc, size, \
  1324.     flag)
  1325. #define CACHEFS_KMEM_FREE(addr, len) \
  1326.     cachefs_kmem_free((caddr_t)addr, len); addr = NULL
  1327. #define CACHEFS_ZONE_ALLOC(zone, flag)    cachefs_zone_alloc(zone, flag)
  1328. #define CACHEFS_ZONE_ZALLOC(zone, flag)    cachefs_zone_zalloc(zone, flag)
  1329. #define CACHEFS_ZONE_FREE(zone, addr) \
  1330.     cachefs_zone_free(zone, (void *)addr) ; addr = NULL
  1331.  
  1332. extern void *cachefs_kmem_alloc(void *(*)(size_t, int), int, int);
  1333. extern void cachefs_kmem_free(caddr_t, int);
  1334. extern void *cachefs_zone_alloc(zone_t *, int);
  1335. extern void *cachefs_zone_zalloc(zone_t *, int);
  1336. extern void cachefs_zone_free(zone_t *, void *);
  1337. extern int cachefs_zone_validate(caddr_t, int);
  1338. extern int cachefs_kmem_validate(caddr_t, int);
  1339. #else /* DEBUG */
  1340.  
  1341. #define CACHEFS_KMEM_ALLOC(size, flag)    kmem_alloc(size, flag)
  1342. #define CACHEFS_KMEM_ZALLOC(size, flag)    kmem_zalloc(size, flag)
  1343. #define CACHEFS_KMEM_FREE(addr, len) \
  1344.     kmem_free((void *)addr, len) ; addr = NULL
  1345. #define CACHEFS_ZONE_ALLOC(zone, flag)    kmem_zone_alloc(zone, flag)
  1346. #define CACHEFS_ZONE_ZALLOC(zone, flag)    kmem_zone_zalloc(zone, flag)
  1347. #define CACHEFS_ZONE_FREE(zone, addr) \
  1348.     kmem_zone_free(zone, (void *)addr) ; addr = NULL
  1349.  
  1350. #endif /* DEBUG */
  1351.  
  1352. #define CACHEFS_RELEASE_FILEHEADER(fidp, fhp) \
  1353.     release_fileheader(fidp, fhp) ; fhp = NULL;
  1354.  
  1355. extern void cachefs_idbg_init(void);
  1356. #ifdef DEBUG
  1357. extern void cache_trace( int, cfstrace_t *, void *, long, long, long, int );
  1358. #endif /* DEBUG */
  1359.  
  1360. extern int fork(void *uap, rval_t *rvp);
  1361.  
  1362. #endif /* defined (_KERNEL) && defined (__STDC__) */
  1363.  
  1364.  
  1365.  
  1366. #ifdef DEBUG
  1367. #define    CFSDEBUG_ALL            0xffffffff    /* all debugging */
  1368. #define    CFSDEBUG_NONE            0x00000000    /* no debugging */
  1369. #define    CFSDEBUG_SUBR            0x00000001    /* debug cachefs_subr.c */
  1370. #define    CFSDEBUG_CNODE            0x00000002    /* debug cachefs_cnode.c */
  1371. #define    CFSDEBUG_RDWR            0x00000004    /* debug read/write ops */
  1372. #define    CFSDEBUG_VOPS            0x00000008    /* debug vnode ops */
  1373. #define    CFSDEBUG_VFSOP            0x00000010    /* debug vfs ops */
  1374. #define    CFSDEBUG_ERROR            0x00000020    /* debug front FS errors */
  1375. #define CFSDEBUG_FSCACHE        0x00000040    /* debug fscache ops */
  1376. #define CFSDEBUG_PROCS            0x00000080    /* debug processes */
  1377. #define CFSDEBUG_FILEHEADER        0x00000100    /* debug file header */
  1378. #define CFSDEBUG_STALE            0x00000200    /* debug ESTALE errors */
  1379. #define CFSDEBUG_RESOURCE        0x00000400
  1380. #define CFSDEBUG_POPULATE        0x00000800
  1381. #define CFSDEBUG_DIO            0x00001000    /* debug direct I/O */
  1382. #define CFSDEBUG_FLUSH            0x00002000
  1383. #define CFSDEBUG_READLINK        0x00004000
  1384. #define CFSDEBUG_BMAP            0x00008000
  1385. #define CFSDEBUG_CFSOPS            0x00010000
  1386. #define CFSDEBUG_LOOKUP            0x00020000
  1387. #define CFSDEBUG_POPDIR            0x00040000    /* debug directory population */
  1388. #define CFSDEBUG_REPLACEMENT    0x00080000    /* debug replacement */
  1389. #define    CFSDEBUG_DIR            0x00100000    /* debug directory ops */
  1390. #define CFSDEBUG_READDIR        0x00100000    /* debug readdir internal ops */
  1391. #define CFSDEBUG_INVAL            0x00200000
  1392. #define CFSDEBUG_ASYNC            0x00400000
  1393. #define CFSDEBUG_NETERR            0x00800000    /* debug network errors */
  1394. #define CFSDEBUG_NOCACHE        0x01000000
  1395. #define CFSDEBUG_ATTR            0x02000000
  1396. #define CFSDEBUG_VALIDATE        0x04000000    /* perform file header validation */
  1397. #define CFSDEBUG_WRITEHDR        0x08000000    /* debug file header writes */
  1398. #define CFSDEBUG_BACKOPS        0x10000000    /* debug back FS ops */
  1399. #define CFSDEBUG_SIZE            0x20000000    /* debug file size changes */
  1400. #define CFSDEBUG_ERROR2            0x40000000    /* debug non-zero errors */
  1401. #define CFSDEBUG_FRONTOPS        0x80000000    /* debug front FS ops */
  1402.  
  1403. #define CNTRACE_ALL            0xffffffff
  1404. #define CNTRACE_NONE        0x0
  1405.  
  1406. /*
  1407.  * trace IDs
  1408.  * all trace IDs must be unique and have no common bits
  1409.  */
  1410. #define CNTRACE_ACT            0x000001    /* trace inactive/reactive */
  1411. #define CNTRACE_WORKQ        0x000002    /* trace workq activity */
  1412. #define CNTRACE_UPDATE        0x000004    /* trace metadata updating */
  1413. #define CNTRACE_DESTROY        0x000008    /* trace CN_DESTROY */
  1414. #define CNTRACE_DIRHOLD        0x000010    /* trace parent dir VN_HOLD */
  1415. #define CNTRACE_HOLD        0x000080    /* trace VN_HOLD operations */
  1416. #define CNTRACE_WRITE        0x000100    /* trace writes */
  1417. #define CNTRACE_READ        0x000200    /* trace reads */
  1418. #define CNTRACE_SIZE        0x000400    /* trace size changes */
  1419. #define CNTRACE_ALLOCMAP    0x000800    /* trace allocmap changes */
  1420. #define CNTRACE_FILEHEADER    0x001000    /* trace changes to c_fileheader */
  1421. #define CNTRACE_ATTR        0x002000    /* trace changes to attributes */
  1422. #define CNTRACE_ALLOCENTS    0x004000    /* trace md_allocents changes */
  1423. #define CNTRACE_WRITEHDR    0x008000    /* trace header writes */
  1424. #define CNTRACE_DIOWRITE    0x010000    /* trace header writes */
  1425. #define CNTRACE_FSYNC        0x020000    /* trace fsync */
  1426. #define CNTRACE_LOOKUP        0x040000    /* trace lookup */
  1427. #define CNTRACE_NOCACHE     0x080000     /* trace CN_NOCACHE */
  1428. #define CNTRACE_POPDIR        0x100000    /* trace dir populations */
  1429. #define CNTRACE_FRONTSIZE    0x200000    /* trace front file size changes */
  1430. #define CNTRACE_INVAL        0x400000    /* trace object invalidation */
  1431.  
  1432. extern int cnodetrace;
  1433.  
  1434. /*
  1435.  * must hold c_statelock as writer when using this macro
  1436.  */
  1437. #ifdef _CNODE_TRACE
  1438. #define CNODE_TRACE(id, cp, addr, v1, v2) \
  1439.     if ( cnodetrace & id) \
  1440.         cache_trace(id, &((cp)->c_trace), (void *)addr, (long)(v1), \
  1441.             (long)(v2), (long)0, __LINE__)
  1442. #else
  1443. #define CNODE_TRACE(id, cp, addr, v1, v2)
  1444. #endif
  1445.  
  1446. #define CACHETRACE_ALL        0xffffffff
  1447. #define CACHETRACE_NONE        0x0
  1448.  
  1449. extern int cachetrace;
  1450.  
  1451. /*
  1452.  * must hold c_contentslock when using this macro
  1453.  */
  1454. #ifdef _CACHE_TRACE
  1455. #define CACHE_TRACE(id, cachep, addr, v1, v2, v3) \
  1456.     if ( cachetrace & id) \
  1457.         cache_trace(id, &((cachep)->c_trace), (void *)addr, (long)(v1), \
  1458.             (long)(v2), (long)(v3), __LINE__)
  1459. #else
  1460. #define CACHE_TRACE(id, cp, addr, v1, v2, v3)
  1461. #endif
  1462.  
  1463. extern cfstrace_t Cachefs_functrace;
  1464. extern int cachefunctrace;
  1465.  
  1466. #define CACHEFS_FUNCTION    0x80000000
  1467.  
  1468. #define CFTRACE_ALL            0xffffffff
  1469. #define CFTRACE_NONE        0
  1470.  
  1471. #define CFTRACE_CREATE        0x00000001
  1472. #define CFTRACE_WRITEHDR    0x00000002
  1473. #define CFTRACE_WRITE        0x00000004
  1474. #define CFTRACE_ALLOC        0x00000008
  1475. #define CFTRACE_OTHER        0x80000000
  1476.  
  1477. #define CACHEFUNC_TRACE(id, addr, arg1, arg2, arg3) \
  1478.     if ( cachefunctrace & id ) \
  1479.         cache_trace(CACHEFS_FUNCTION, &Cachefs_functrace, (void *)addr, \
  1480.             (long)(arg1), (long)(arg2), (long)(arg3), __LINE__);
  1481.  
  1482. extern int cachefsdebug;
  1483.  
  1484. #define    CFS_DEBUG(N, OP)    if (cachefsdebug & (N)) OP
  1485.  
  1486. extern uint _ftext[];
  1487. extern uint _etext[];
  1488.  
  1489. /*
  1490.  * a valid address is not in kernel text and is not in page 0
  1491.  */
  1492. #define VALID_ADDR(addr)    ((((u_long)(addr) > (u_long)_etext) || \
  1493.                                 ((u_long)(addr) < (u_long)_ftext)) && \
  1494.                                 (pnum(addr) != 0))
  1495. #else /* DEBUG */
  1496. #define CFS_DEBUG(N, OP)
  1497. #define CNODE_TRACE(id, cp, addr, v1, v2)
  1498. #define CACHE_TRACE(id, cp, addr, v1, v2, v3)
  1499. #define CACHEFUNC_TRACE(id, addr, arg1, arg2, arg3)
  1500. #endif /* DEBUG */
  1501.  
  1502. #define    C_ISVDEV(t) ((t == VBLK) || (t == VCHR) || (t == VFIFO))
  1503.  
  1504. #ifdef __cplusplus
  1505. }
  1506. #endif
  1507.  
  1508. #endif /* _SYS_FS_CACHEFS_FS_H */
  1509.